import { Inject, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { LoginDto } from './dto/login.dto';
import { BusinessException } from '@/common';
import Redis from 'ioredis';
import { RedisKeys } from '@/common/enum/RedisKeys';
import { UserService } from '../user/user.service';
@Injectable()
export class AuthService {
  constructor(
    @Inject('REDIS') private redis: Redis,
    private readonly jwtService: JwtService,
    private readonly userService: UserService
  ) {}

  // 登录用户验证
  async validateAccount(loginDto: LoginDto): Promise<any> {
    const { username, password, code, codeId } = loginDto;

    // 从redis中获取验证码
    const verityCode = await this.redis.get(
      `${RedisKeys.LOGIN_CODE}:${codeId}`
    );

    // code 失效
    if (!verityCode) {
      throw new BusinessException({ code: 400, message: '验证码过期' });
    }

    // code 验证
    if (code.toLocaleLowerCase() !== verityCode?.toLocaleLowerCase()) {
      throw new BusinessException({ code: 400, message: '验证码错误' });
    }

    // 根据用户名查询角色
    const user = await this.userService.findOneByUsername(username);

    if (!user) {
      throw new BusinessException({ code: 400, message: '账号或密码错误' });
    }

    // 密码校验 - 非加密逻辑
    if (user.password !== password) {
      throw new BusinessException({ code: 400, message: '账号或密码错误' });
    }

// 通过验证后需要传出的用户信息
    return {
      username: user?.username ?? '',
      id: user?.id ?? null,
      roles: user?.roles ?? [],
      avatar: user?.avatar?.url ?? '',
      isAdmin: user?.isAdmin ?? 0
    };
  }

  // 登录功能
  login(user: any) {
    // token 载荷处理 - 将用户信息加密
    const payload = {
      username: user.username,
      avatar: user.avatar,
      userId: user.id,
      roles: user.roles,
      isAdmin: user.isAdmin
    };
    // jwt 加密 - `Bearer ` + token
    const access_token = this.jwtService.sign(payload);

    // redis 持久化
    this.redis.del(RedisKeys.LOGIN_CODE);
    this.redis.sadd(RedisKeys.USER_TOKEN, access_token);

    return {
      userId: user.id,
      access_token // 加密后的token令牌返回
    };
  }

  logout(access_token: string) {
    return this.redis.srem(RedisKeys.USER_TOKEN, access_token);
  }
}
